<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h3 id="hMyname">{myname}</h3>
    <p id="pMyname">{myname}</p>
    <h3 id="hMyage">{myage}</h3>
    <p id="pMyage">{myage}</p>

    <script>
        function registerProperties(obj, properties) {
            properties.forEach(
                p => {
                    console.log("p",p);
                    obj.propListeners = obj.propListeners || {}

                    obj.propListeners[p.name] = new Set()
                    p.listeners.forEach(
                        lis => obj.propListeners[p.name].add(lis)
                    )

                    Object.defineProperty(obj, p.name, {
                        get() {
                            console.log("getter");
                            return obj["stored_" + p.name]
                        },
                        set(newValue) {
                            console.log("setter", newValue);
                            obj["stored_" + p.name] = newValue

                            p.listeners.forEach(
                                lis => {
                                    lis.innerText = newValue
                                    console.log(lis, "'s innerText has changed to", newValue);
                                }
                            )
                        }
                    })
                
                }
            )
        }
        
        const data = {}
    </script>

    <script>
        registerProperties(data, [
            { name: "myname", listeners: [hMyname, pMyname] },
            { name: "myage", listeners: [hMyage, pMyage] },
        ])
        data.myname = "黑哥"
        data.myage = 40

        setTimeout(() => {
            data.myname = "白鸽"
            data.myage = 35
        }, 3000);
    </script>
</body>

</html>